package cn.qyd.aqs;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 邱运铎
 * @date 2024-03-20 11:30
 */
public class ConditionBoundedBufferDemo<T> {
    private final LinkedList<T> buffer;
    private final ReentrantLock lock;
    private final int capacity;
    private final Condition onFull;
    private final Condition onEmpty;

    public ConditionBoundedBufferDemo(int capacity) {
        this.capacity = capacity;
        this.buffer = new LinkedList<>();
        this.lock = new ReentrantLock();
        this.onFull = lock.newCondition();
        this.onEmpty = lock.newCondition();
    }

    public void push(T t) throws InterruptedException {
        lock.lock();
        try {
            while (capacity == buffer.size()) {
                System.out.println(Thread.currentThread().getName() + " : 缓冲区已满，进入等待队列....，当前t: --" + t);
                onFull.await();
                System.out.println(Thread.currentThread().getName() + " :  该线程在缓冲区已满等待队列被唤醒...., 当前t: --" + t);
            }
            buffer.add(t);
            System.out.println(Thread.currentThread().getName() + " : 往缓冲区添加元素: --" + t);
            onEmpty.signal();
            System.out.println(Thread.currentThread().getName() + " : 调用唤醒处于缓冲区空闲等待队列的任务 ");
        } finally {
            System.out.println("push方法的finally,我被执行了，当前t: --" + t);
            lock.unlock();
        }
    }

    public T pop() throws InterruptedException {
        lock.lock();
        try {
            while (buffer.isEmpty()) {
                System.out.println(Thread.currentThread().getName() + " : ++++++++++++++++++++++++++++缓冲区空闲，进入等待队列....");
                onEmpty.await();
                System.out.println(Thread.currentThread().getName() + " :  +++++++++++++++++++++++++++该线程在缓冲区空闲等待队列被唤醒....");
            }
            T item = buffer.removeFirst();
            System.out.println(Thread.currentThread().getName() + " : 从缓冲区移除元素: " + item);
            onFull.signal();
            System.out.println(Thread.currentThread().getName() + " : 调用唤醒处于缓冲区已满等待队列的任务 ");
            return item;
        } finally {
            lock.unlock();
            System.out.println("pop的finally，我被执行了");
        }
    }

    public static void main(String[] args) {
        ConditionBoundedBufferDemo<Integer> demo = new ConditionBoundedBufferDemo<>(5);
        new Thread(() -> {
           for (int i = 0; i < 20; i++) {
               try {
                   demo.push(i);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
        }).start();

        new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
                    demo.pop();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();

    }
}
